#include <stdio.h>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

class Phone
{
public:
    Phone(int o, int h, int p):pos(o),home(h),phone7(p){}
    int home;
    int phone7;
    int pos;
};

class PhoneHome
{
public:
    string province;    //省份
    string city;        //城市
    string zipCode;     //邮编
    string areaCode;    //区号
    int addrOff;        //索引

    vector<Phone> phoneList;
};

void addStr (string str, vector<char>&buf)
{    
    int tt = buf.size();
    buf.resize(tt + str.size());
    copy(str.begin(), str.end(), &buf[tt]);
}


int main()
{
    ifstream phoneFile("phone.dat", ios::in | ios::binary);

    if(!phoneFile){
        cout << "read file error" <<endl;
        return 0;
    }
    
    phoneFile.seekg(0, ios::end);
    int lenght = phoneFile.tellg();    
    phoneFile.seekg(0, ios::beg);

    cout << "lenght:" << lenght << endl;

    uint8_t *buf = new uint8_t[lenght];
    phoneFile.read((char *)buf, lenght*sizeof(char));

    phoneFile.close();

    for(int i=0; i<4; i++)
        cout << hex << setw(2) << setfill('0') << (int)buf[i] << " ";

    int offPhone = buf[4] | buf[5] << 8 | buf[6] << 16 | buf[7] << 24;;
    cout << hex << setw(2) << setfill('0') << offPhone << " ";

    for(int i=8; i<11; i++)
        cout << hex << setw(2) << setfill('0') << (int)buf[i] << " ";

    cout << endl;

#if 1
    vector<Phone> PhoneList;
    vector<PhoneHome> mPhoneHomeList;
    PhoneHome *mPhoneHome = new PhoneHome();
    string str;
    int index = 0;
    int pos = 0, n = 0;
    for (int i = 8; i < offPhone; ++i)
    {
        pos = i;
        while (buf[i] != 0x7c)
        {
            if(buf[i] == 0x00) break;

            str += buf[i]; 
            ++i;
        }
        
        if(n == 0)
        {
            mPhoneHome->province = str;
            mPhoneHome->addrOff = pos;         
        }
        else if(n == 1)
        {
            mPhoneHome->city = str;
        }
        else if(n == 2)
        {
            mPhoneHome->zipCode = str;
        }
        else
        {
            mPhoneHome->areaCode = str;
            mPhoneHomeList.push_back(*mPhoneHome); 
        }
        
        n++;
        if(n>3) n=0;
        index += str.size();
        str.clear();
    }

    for(int i = offPhone; i < lenght; i+=9)
    {
        int phone7 = buf[i] | buf[i + 1] << 8 | buf[i + 2] << 16 | buf[i + 3] << 24;
        int pos =  buf[i+4] | buf[i + 5] << 8 | buf[i + 6] << 16 | buf[i + 7] << 24;
        int home = buf[i+8];

        PhoneList.push_back(Phone(pos, home, phone7));
    }


    for(int j=0; j < mPhoneHomeList.size(); ++j)
    {
        for(auto phone : PhoneList)
        {
            if(phone.pos ==  mPhoneHomeList[j].addrOff)
            {
                mPhoneHomeList[j].phoneList.push_back(phone);                
            }                
        }
    }

    index += 8;
    index += mPhoneHomeList.size() * 8;
    cout << hex << index << endl;
    // cout << dec << index << endl;

    int addcount = 8 - index % 4;
    index += addcount;


#endif
    

    vector<char> newBuf;
    for(int i=0; i<4; i++)
    {
        newBuf.emplace_back(buf[i]);
    }
    // newBuf.emplace_back((char)(index>>24));
    newBuf.emplace_back((char)(index>>16));
    newBuf.emplace_back((char)(index>>8));
    newBuf.emplace_back((char)index);

    newBuf.emplace_back(0x7f);

    int phoneCount=0;
    for(auto item : mPhoneHomeList)
    {
        addStr(item.province, newBuf);
        newBuf.emplace_back(0x7c);
        addStr(item.city, newBuf);
        newBuf.emplace_back(0x7c);
        addStr(item.zipCode, newBuf);
        newBuf.emplace_back(0x7c);
        addStr(item.areaCode, newBuf);
        newBuf.emplace_back(0x7c);

        int phonecount = item.phoneList.size();
        index += phonecount * 4;
        newBuf.emplace_back((char)(index>>16));
        newBuf.emplace_back((char)(index>>8));
        newBuf.emplace_back((char)index);
        newBuf.emplace_back(0x7c);

        phoneCount += phonecount;
    }
    cout << hex << index << endl;

    
    for(int i=0; i<addcount; i++)
    {
        newBuf.emplace_back(0x7f);
    }

    char *newBuff= new char[phoneCount*4];
    int buffindex = 0;
    for(auto mPhoneHome : mPhoneHomeList)
    {       
        for(auto item : mPhoneHome.phoneList)
        {
            newBuff[buffindex++] = (char)(item.phone7 >> 16);
            newBuff[buffindex++] = (char)(item.phone7 >> 8);
            newBuff[buffindex++] = (char)item.phone7;
            newBuff[buffindex++] = (char)item.home;
        }
    }

    ofstream addrFile("phonehome.dat", ios::out | ios::binary);
    addrFile.write(&newBuf[0],  newBuf.size()*sizeof(char));
    addrFile.write(&newBuff[0],  phoneCount*4*sizeof(char));
    addrFile.close();

    delete newBuff;

    return 0;
}



